ShaderGraph検証 : Dodge(覆い焼きカラー)
1. 数式の考察
覆い焼きの挙動を見る前に、覆い焼きの数式を見ていきたいと思います。
覆い焼きカラーはDodge (Color Dodge)とも呼ばれます。
Dodgeと似た名前のLinear Dodgeがありますが、こちらは加算を意味する言葉です。
覆い焼き(Dodge)の計算式
覆い焼きの計算式は以下のようになります。
$ C = \frac {A}{(1 - B)}
$ A : 元から描画されている色 (0 \leqq A \leqq 1)
$ B : 上から重ねる色 (0 \leqq B \leqq 1)
$ C : AとBを合成した結果の色
Bを固定した場合のグラフ
計算式$ C = \frac {A}{(1 - B)}のBを固定してAを変化させた場合、Cは直線のグラフを描きます。
https://gyazo.com/bf2094f4c0f1ae82ed61c452bfbcf231
補足)
$ C = \frac {A}{(1 - B)}を変形すると、$ C = \frac {1}{(1 - B)}・Aになります。
これは傾きを $ \frac {1}{(1 - B)}とする直線の式になっています。
Aを固定した場合のグラフ
計算式$ C = \frac {A}{(1 - B)}のAを固定してBを変化させた場合、Cは曲線のグラフを描きます。
Aが0に近づくほど、Bの変化が急になっていくことが読み取れます。
https://gyazo.com/0646c70b1b6362375d0415d1f18539bf https://gyazo.com/e7bfac40d122dd6d247c0322920bf5b3 https://gyazo.com/44582a7d7802fdfa57d3288cc88853a8
補足)
$ C = \frac {A}{1 - B}は$ C = \frac {A}{B}を左右反転させたようなグラフになっています。
2. 覆い焼き(Dodge)の内部実装
code:Dodge(glsl)
void Unity_Blend_Dodge_float4(float4 Base, float4 Blend, float Opacity, out float4 Out)
{
Out = Base / (1.0 - Blend);
Out = lerp(Base, Out, Opacity);
}
3. シェーダーグラフで検証
実際にShaderGraphを使い、覆い焼きカラー(Dodge)がどういったふるまいをするのかを観察してみました。
環境
Unity2020.1.0a14
ShaderGraph (Version 7.1.1)
Universal RP (Version 7.1.1)]
検証1 : A = 0, B = 1
A = 0, B = 1として Blendノード(Mode = Dodge)へ入力してみました。 結果は黒色(C = 0)になっています。
https://gyazo.com/d3c3a764f7efb7eee1f1648b096ebcd7
Cは計算式$ C = \frac {A}{(1 - B)}で計算することできます。
これに A = 0, B = 1を代入すると以下のようになります。
$ C = \frac {0}{(1 - 1)} = \frac {0}{0}
Cは$ 0 \div 0となっていて数学的には計算不可能ですが、ShaderGraph上ではなぜか黒色(C = 0)という結果を示しています。
検証2 : A = 0.1, B = 1
今度はA = 0.1, B = 1として Blendノード(Mode = Dodge)へ入力してみました。 結果は白色になっています。
https://gyazo.com/9ee7deae7c7816029ea183c1abd344ed
Cは計算式$ C = \frac {A}{(1 - B)}で計算することできます。
これに A = 0.1, B = 1を代入すると以下のようになります。
$ C = \frac {0.1}{(1 - 1)} = \frac {0.1}{0} = (巨大な数)
ShaderGraph上では1.0より大きい値はすべて白色として表示されるため、上記の計算結果も白色になるはずです。
Bが0に近い(またはB = 0)の場合は Cは白色になると言えそうです。
検証3 : A = 1, B = 0
A = 1, B = 0として Blendノード(Mode = Dodge)へ入力してみました。 結果は白色になっています。
https://gyazo.com/42908d5c6333f6c14ce5cd92fc68fd4b
Cは計算式$ C = \frac {A}{(1 - B)}で計算することできます。
これに A = 1, B = 0を代入すると以下のようになります。
$ C = \frac {1}{(1 - 0)} = \frac {1}{1} = 1
C=1(白色)となり、これはShaderGraphの表示と一致しています。
検証4 : A = 0.5, B = 0
A = 0.5, B = 0として Blendノード(Mode = Dodge)へ入力してみました。 AとCは同じ色になっているように見えます。
https://gyazo.com/43084f93919458d613ffd4d932220ab8
Cは計算式$ C = \frac {A}{(1 - B)}で計算することできます。
ここで、 B = 0を代入すると以下のようになります。
$ C = \frac {A}{(1 - 0)} = \frac {A}{1} = A
つまり、以下が成立します。
$ C = A
B = 0の場合、A とC は必ず同じ色になると言えます。